#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFZISE 8192
#define DEFAULT_PORT 5320
#define CMAX 256

enum {CMD_NAME, DST_IP, DST_PORT};

int main(int argc, char *argv[])
{
	struct addrinfo info, *res;
	char ip[CMAX];
	int s;
	int n;
	char buf[BUFZISE];
	char cmd[BUFZISE];
	struct timeval tv;
	fd_set readfd;

	if(argc != 2 && argc != 3) {
		fprintf(stderr, "Usage: %s hostname[port] \n",argv[0]);
		exit(EXIT_FAILURE);
	}

	memset(&info,0, sizeof(info));
	info.ai_flags = AI_CANONNAME;
	info.ai_family = AF_UNSPEC;
	info.ai_socktype = SOCK_STREAM;

	if(getaddrinfo(argv[DST_IP], (argc == 3)?argv[DST_PORT]:DEFAULT_PORT,&info, &res) !=0)	{
		perror("getaddrinfo");
		exit(EXIT_FAILURE);
	}

	if((s = socket(res->ai_family, res->ai_socktype, 0)) < 0) {
		perror("connect");
		exit(EXIT_FAILURE);
	}

	if(res->ai_family == AF_INET6)
		printf("connected to %s by IPv6\n", inet_ntop(AF_INET6,&(((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr), ip, CMAX));
	else if(res->ai_family == AF_INET)
		printf("connected to %s by IPv4\n", inet_ntop(AF_INET,&(((struct sockaddr_in *)(res->ai_addr))->sin_addr), ip, CMAX));
	else
		printf("connected by no IPv4/IPv6.\n");

	while(1) {
		tv.tv_sec = 600;
		tv.tv_usec = 0;

		FD_ZERO(&readfd);
		FD_SET(0, &readfd);
		FD_SET(s, &readfd);

		if((select(s+1, &readfd, NULL, NULL, &tv)) <= 0) {
			fprintf(stderr,"/n Timeout\n");
			break;
		}

		if(FD_ISSET(0, &readfd)) {
			if((n = read(0, buf, BUFZISE-1)) <= 0)
				break;
			buf[n] = '\0';
			sscanf(buf, "%s", cmd);
	
			if(strcmp(cmd, "quit") == 0)
				break;
			if(send(s, buf, n, 0) <= 0)
				break;
		}

		if(FD_ISSET(s, &readfd)) {
			if((n = recv(s, buf, BUFZISE-1, 0)) <= 0) {
				fprintf(stderr, "connection closed.\n");
				exit(EXIT_FAILURE);
			}
			buf[n] = '\0';
			printf("%s",buf);
			fflush(stdout);
		}
	}

	strcpy(buf, "quit");
	send(s, buf, n, 0);
	close(s);
	printf("connection closed.\n");

	return EXIT_SUCCESS;
}
